package com.px.baolaiapi.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Preconditions;
import com.px.common.api.CommonPage;
import com.px.common.api.CommonResult;
import com.px.common.constant.Constant;
import com.px.mbg.mapper.MiscellaneousReceiptMapper;
import com.px.mbg.model.*;
import com.px.baolaiapi.dto.MiscellaneousReceiptDto;
import com.px.baolaiapi.enums.ReceiptsTypeEnum;
import com.px.baolaiapi.page.MiscellaneousReceiptPage;
import com.px.baolaiapi.service.*;
import com.px.baolaiapi.util.JwtTokenUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 杂收单 服务实现类
 * </p>
 *
 * @author 品讯科技
 * @since 2022-03-25
 */
@Service
public class MiscellaneousReceiptServiceImpl extends ServiceImpl<MiscellaneousReceiptMapper, MiscellaneousReceipt> implements IMiscellaneousReceiptService {
    @Autowired
    private ISequenceNumberService sequenceNumberService;
    @Autowired
    private IMiscellaneousReceiptDetailService miscellaneousReceiptDetailService;
    @Autowired
    private IToDoListService toDoListService;
    @Autowired
    private IDocumentTypeService documentTypeService;
    @Autowired
    private IBomService bomService;
    @Autowired
    private IInOutOfBillService inOutOfBillService;
    @Autowired
    private ICommonBillService commonBillService;
    @Autowired
    private JwtTokenUtils jwtTokenUtils;

    @Autowired
    private IUnitCnvRateService unitCnvRateService;
    @Autowired
    private IUnitService unitService;



    @Override
    public void addMiscellaneousReceipt(MiscellaneousReceiptDto miscellaneousReceiptDto) {
        MiscellaneousReceipt bill = new MiscellaneousReceipt();
        BeanUtils.copyProperties(miscellaneousReceiptDto, bill);

        ReceiptsTypeEnum receiptsTypeEnum = ReceiptsTypeEnum.ZSD;
        bill.setReceiptsType(receiptsTypeEnum.getValue());

        String bnoType = bill.getBnoType();
        Preconditions.checkArgument(StringUtils.isNotBlank(bnoType), "单据类型必选");
        //String bnoNo = sequenceNumberService.createSequenceNumberRod(bnoType, "yyyy", 4, StrUtil.DASHED);
        String bnoNo = sequenceNumberService.createSequenceNumberRod("BLZS", "yyMM", 4, "");
        bill.setBnoNo(bnoNo);

        Users user = jwtTokenUtils.getUser();
        bill.setUserName(user.getUsername());
        bill.setUserAccount(user.getAccount());

        // 记账期间是制单日期的年月
        String createDate = bill.getCreateDate();
        DateTime parse = DateUtil.parse(createDate, DatePattern.NORM_DATETIME_PATTERN);
        bill.setCreateDatePeriod(DateUtil.format(parse, "yyyy-MM"));

        bill.setFinishFlag(Constant.ORDER_FINISH_FLAG.UN_FINISH);

        if (this.save(bill)) {
            List<MiscellaneousReceiptDetail> miscellaneousReceiptDetails = miscellaneousReceiptDto.getMiscellaneousReceiptDetails();
            miscellaneousReceiptDetails.forEach(e -> {
                e.setMiscellaneousReceiptId(bill.getId());

                //String batchNo = commonBillService.genBatchNo(bnoType);

                String batchNo =  bnoNo + "-" + sequenceNumberService.getSequenceNumber(bnoNo,4);
                e.setBatchNo(batchNo);
            });
            if (CollectionUtil.isNotEmpty(miscellaneousReceiptDetails)) {
                miscellaneousReceiptDetailService.saveBatch(miscellaneousReceiptDetails);
            }
        }

        // 添加待办任务记录
        StringJoiner client = new StringJoiner("/");
        if(StringUtils.isNotBlank(bill.getCustomerName())){
            client.add(bill.getCustomerName());
        }
        if(StringUtils.isNotBlank(bill.getSupplierName())){
            client.add(bill.getSupplierName());
        }
        toDoListService.addToDoList(bill.getId(), bill.getBnoNo(), receiptsTypeEnum,bill.getBnoType(), client.toString());

    }

    @Override
    public CommonPage queryMiscellaneousReceiptPage(MiscellaneousReceiptPage page) {
        LambdaQueryWrapper<MiscellaneousReceipt> queryWrapper = Wrappers.lambdaQuery(MiscellaneousReceipt.class);
        String receiptsTypeU9 = page.getBnoType();
        if (StringUtils.isNotEmpty(receiptsTypeU9)) {
            queryWrapper.like(MiscellaneousReceipt::getBnoType, receiptsTypeU9);
        }

        String oddNum = page.getBnoNo();
        if (StringUtils.isNotEmpty(oddNum)) {
            queryWrapper.like(MiscellaneousReceipt::getBnoNo, oddNum);
        }

        String beneficiary = page.getUserName();
        if (StringUtils.isNotEmpty(beneficiary)) {
            queryWrapper.like(MiscellaneousReceipt::getUserName, beneficiary);
        }

        String benefitDepartment = page.getDeptName();
        if (StringUtils.isNotEmpty(benefitDepartment)) {
            queryWrapper.like(MiscellaneousReceipt::getDeptName, benefitDepartment);
        }

        String startMakeDate = page.getStartMakeDate();
        if (StringUtils.isNotEmpty(startMakeDate)) {
            queryWrapper.ge(MiscellaneousReceipt::getCreateDate, startMakeDate);
        }
        String endMakeDate = page.getEndMakeDate();
        if (StringUtils.isNotEmpty(endMakeDate)) {
            queryWrapper.le(MiscellaneousReceipt::getCreateDate, endMakeDate);
        }
        queryWrapper.eq(page.getFinishFlag() != null && page.getFinishFlag() >= 0, MiscellaneousReceipt::getFinishFlag, page.getFinishFlag());
        queryWrapper.eq(MiscellaneousReceipt::getIsDelFlag, Constant.IS_ENABLED.ENABLE);
        queryWrapper.orderByDesc(MiscellaneousReceipt::getUpdatedTime);

        CommonPage commonPage = CommonPage.restPage(this.page(new Page<>(page.getPageNum(), page.getPageRow()), queryWrapper));
        List<MiscellaneousReceipt> miscellaneousReceiptList = commonPage.getList();

        List<JSONObject> jsonObjects = new ArrayList<>();
        for (MiscellaneousReceipt miscellaneousReceipt : miscellaneousReceiptList) {

            JSONObject jsonObject = billToJSONObject(miscellaneousReceipt);
            jsonObjects.add(jsonObject);
        }
        commonPage.setList(jsonObjects);
        return commonPage;
    }

    @Override
    public JSONObject queryMiscellaneousDeliveryById(long id) {
        MiscellaneousReceipt miscellaneousReceipt = this.getById(id);
        if (ObjectUtil.isNotEmpty(miscellaneousReceipt)) {

            JSONObject jsonObject = billToJSONObject(miscellaneousReceipt);

            List<JSONObject> dtoList = new ArrayList();
            List<MiscellaneousReceiptDetail> list = miscellaneousReceiptDetailService.list(new QueryWrapper<MiscellaneousReceiptDetail>().lambda().eq(MiscellaneousReceiptDetail::getMiscellaneousReceiptId, id).eq(MiscellaneousReceiptDetail::getIsDelFlag, Constant.IS_ENABLED.ENABLE));
            if(CollectionUtils.isNotEmpty(list)){
                for (MiscellaneousReceiptDetail detail : list) {


                    // 实收重量
                    String pcsWeight = "";
                    // 单位转换率转换完重量
                    String weightUnit = "";

                    JSONObject dto = JSONUtil.parseObj(detail);
                    BigDecimal rNum = inOutOfBillService.getSumRealNumByBnoNoAndDetailId(miscellaneousReceipt.getBnoNo(), detail.getId());
                    dto.set("rNum", rNum);
                    Map<String, Object> unitCN = bomService.getUnitCN(detail.getWidthUnit(), detail.getLengthUnit(), detail.getThicknessUnit(), detail.getCvpUnit(), detail.getPcsUnit());
                    dto.putAll(unitCN);


                    // 组织单位转换率数据
                    UnitCnvRate unitCnvRate = unitCnvRateService.queryUnitCnvRateByBomCodeAndUnit(detail.getMaterialCode(),detail.getPcsUnit());
                    if (ObjectUtil.isNotNull(unitCnvRate)) {
                        pcsWeight = String.valueOf(unitCnvRate.getCnvRate().multiply(detail.getPcsNum()).setScale(2, BigDecimal.ROUND_UP));
                        Unit unit = unitService.queryUnitByCode("",unitCnvRate.getTgtUnit());
                        if (ObjectUtil.isNotNull(unit)) {
                            weightUnit = unit.getUnitName();
                        }
                    }

                    dto.set("pcsWeight", pcsWeight);
                    dto.set("weightUnit",weightUnit);




                    dtoList.add(dto);
                }
            }
            jsonObject.set("miscellaneousReceiptDetails", dtoList);

            return jsonObject;
        }
        return new JSONObject();
    }

    private JSONObject billToJSONObject(MiscellaneousReceipt miscellaneousReceipt){
        JSONObject dto = JSONUtil.parseObj(miscellaneousReceipt);
        //转换单据类型(U9)
        //单据类型同步后,获取位置变更

        DocumentType documentType = documentTypeService.getById(miscellaneousReceipt.getBnoType());
        if (ObjectUtil.isNotNull(documentType)) {
            dto.set("bnoTypeName", documentType.getName());
        }else{
            dto.set("bnoTypeName","");
        }
        return dto;
    }

    
    public Object generateU9Data(String bnoNo, List<InOutOfBill> inOutOfBillList) {
        JSONObject jsonObject = new JSONObject();
        MiscellaneousReceipt miscellaneousReceipt = this.getOne(new QueryWrapper<MiscellaneousReceipt>().lambda().eq(MiscellaneousReceipt::getBnoNo,bnoNo).eq(MiscellaneousReceipt::getIsDelFlag,Constant.IS_ENABLED.ENABLE));
        jsonObject.set("organizationId",miscellaneousReceipt.getOrganizationId());
        jsonObject.set("organizationCode",miscellaneousReceipt.getOrganizationCode());
        jsonObject.set("organizationName",miscellaneousReceipt.getOrganizationName());
        jsonObject.set("bnoType",miscellaneousReceipt.getBnoType());
        jsonObject.set("bnoNo",miscellaneousReceipt.getBnoNo());
        jsonObject.set("createDate",miscellaneousReceipt.getCreateDate());
        jsonObject.set("createDatePeriod",miscellaneousReceipt.getCreateDatePeriod());
        jsonObject.set("bnoStatus",Constant.U9_BNO_STATUS.CLOSE);
        jsonObject.set("storeAddress",inOutOfBillList.get(0).getStgeCode());
        jsonObject.set("storeKeeperCode",inOutOfBillList.get(0).getUserAccount());
        jsonObject.set("storeKeeperName",inOutOfBillList.get(0).getUserName());
        jsonObject.set("supplierCode",miscellaneousReceipt.getSupplierCode());
        jsonObject.set("supplierName",miscellaneousReceipt.getSupplierName());
        jsonObject.set("customerCode",miscellaneousReceipt.getCustomerCode());
        jsonObject.set("customerName",miscellaneousReceipt.getCustomerName());
        jsonObject.set("userAccount",miscellaneousReceipt.getUserAccount());
        jsonObject.set("userName",miscellaneousReceipt.getUserName());
        jsonObject.set("deptCode",miscellaneousReceipt.getDeptCode());
        jsonObject.set("deptName",miscellaneousReceipt.getDeptName());
        JSONArray jsonArray = new JSONArray();
        for (InOutOfBill inOutOfBill : inOutOfBillList) {
            MiscellaneousReceiptDetail detail = miscellaneousReceiptDetailService.getById(inOutOfBill.getBillDetailId());
            JSONObject jsonDetail = new JSONObject();
            jsonDetail.set("lineNo",detail.getLineNo());
            jsonDetail.set("materialCode",detail.getMaterialCode());
            jsonDetail.set("materialName",detail.getMaterialName());
            jsonDetail.set("specification",detail.getSpecification());
            jsonDetail.set("pcsNum",inOutOfBill.getQty());
            jsonDetail.set("pcsUnit",inOutOfBill.getUnit());
            jsonDetail.set("cvpNum",inOutOfBill.getWeight());
            jsonDetail.set("cvpUnit",inOutOfBill.getWeightUnit());
            jsonDetail.set("longt",inOutOfBill.getLongt());
            jsonDetail.set("lengthUnit",inOutOfBill.getLengthUnit());
            jsonDetail.set("width",inOutOfBill.getWidth());
            jsonDetail.set("widthUnit",inOutOfBill.getWidthUnit());
            jsonDetail.set("thickness",inOutOfBill.getThickness());
            jsonDetail.set("thicknessUnit",inOutOfBill.getThicknessUnit());
            jsonDetail.set("storeAddress",inOutOfBill.getStgeCode());
            jsonDetail.set("storeBinCode",inOutOfBill.getStgeLocCode());
            jsonDetail.set("batchNo",detail.getBatchNo());
            jsonDetail.set("supplierCode",miscellaneousReceipt.getSupplierCode());
            jsonDetail.set("supplierName",miscellaneousReceipt.getSupplierName());
            jsonDetail.set("customerCode",miscellaneousReceipt.getCustomerCode());
            jsonDetail.set("customerName",miscellaneousReceipt.getCustomerName());
            jsonArray.add(jsonDetail);
        }
        jsonObject.set("items",jsonArray);

        return jsonObject;
    }

    /**
     * 存储从U9接收到的杂收单数据
     * @param datas mes交互数据
     * @return
     */
        public CommonResult operationInterface(Object datas) {
        JSONObject jsonObject = JSONUtil.parseObj(datas);
        MiscellaneousReceipt miscellaneousReceipt = new MiscellaneousReceipt();
        miscellaneousReceipt.setOrganizationId(jsonObject.getLong("organizationId"));
        miscellaneousReceipt.setOrganizationCode(jsonObject.getStr("organizationCode"));
        miscellaneousReceipt.setOrganizationName(jsonObject.getStr("organizationName"));
        miscellaneousReceipt.setBnoType(jsonObject.getStr("bnoType"));
        miscellaneousReceipt.setBnoNo(jsonObject.getStr("bnoNo"));
        miscellaneousReceipt.setCreateDate(jsonObject.getStr("createDate"));
        miscellaneousReceipt.setCreateDatePeriod(jsonObject.getStr("createDatePeriod"));
        miscellaneousReceipt.setSupplierCode(jsonObject.getStr("supplierCode"));
        miscellaneousReceipt.setSupplierName(jsonObject.getStr("supplierName"));
        miscellaneousReceipt.setCustomerCode(jsonObject.getStr("customerCode"));
        miscellaneousReceipt.setCustomerName(jsonObject.getStr("customerName"));
        miscellaneousReceipt.setBenefitUserAccount(jsonObject.getStr("userAccount"));
        miscellaneousReceipt.setBenefitUserName(jsonObject.getStr("userName"));
        miscellaneousReceipt.setDeptCode(jsonObject.getStr("deptCode"));
        miscellaneousReceipt.setDeptName(jsonObject.getStr("deptName"));
        if(this.save(miscellaneousReceipt)){
            JSONArray jsonArray = jsonObject.getJSONArray("items");
            for (Object o : jsonArray) {
                JSONObject jDetail = JSONUtil.parseObj(o);
                MiscellaneousReceiptDetail detail = new MiscellaneousReceiptDetail();
                detail.setOrganizationId(miscellaneousReceipt.getOrganizationId());
                detail.setMiscellaneousReceiptId(miscellaneousReceipt.getId());
                detail.setLineNo(jDetail.getStr("lineNo"));
                detail.setMaterialCode(jDetail.getStr("materialCode"));
                detail.setMaterialName(jDetail.getStr("materialName"));
                detail.setPcsNum(jDetail.getBigDecimal("pcsNum"));
                detail.setPcsUnit(jDetail.getStr("pcsUnit"));
                detail.setCvpNum(jDetail.getBigDecimal("cvpNum"));
                detail.setCvpUnit(jDetail.getStr("cvpUnit"));
                detail.setSupplierCode(jDetail.getStr("supplierCode"));
                detail.setSupplierName(jDetail.getStr("supplierName"));
                detail.setCustomerCode(jDetail.getStr("customerCode"));
                detail.setCustomerName(jDetail.getStr("customerName"));
                miscellaneousReceiptDetailService.save(detail);
            }
            return CommonResult.success("");
        }
        return CommonResult.failed("操作失败");
    }
}
